package cn.cellcom.agent.struts.action;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.hibernate.classic.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.cellcom.agent.biz.TUserBiz;
import cn.cellcom.agent.common.AgentConstant;
import cn.cellcom.agent.common.AgentConstant.AGENT_STATUS;
import cn.cellcom.agent.common.AgentConstant.SESSION_STEP;
import cn.cellcom.agent.entity.MonitorPandect;
import cn.cellcom.agent.online.client.AgentClient;
import cn.cellcom.agent.online.client.ClientManager;
import cn.cellcom.agent.online.client.SessionManager;
import cn.cellcom.agent.online.client.SessionPool;
import cn.cellcom.agent.online.wrapper.SessionWrapper;
import cn.cellcom.agent.pojo.TUser;
import cn.cellcom.jar.biz.struts.CommonForm;
import cn.cellcom.jar.dao.IBaseDao;
import cn.cellcom.jar.logon.LogonSession;
import cn.cellcom.jar.util.CU;
import cn.cellcom.jar.util.DT;
import cn.cellcom.jar.util.MyException;

/**
 * 监控处理类
 * 
 * @author 郑余杰
 */
public class MonitorDpAct extends DispatchAction {

	private Logger log = LoggerFactory.getLogger(this.getClass());

	private TUserBiz ubiz;

	private IBaseDao dao;

	public ActionForward pandect(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse rep) {
		long start = System.currentTimeMillis();

		CommonForm fm = (CommonForm) form;
		MonitorPandect pandect = new MonitorPandect();
		LogonSession ls = new LogonSession(req);
		TUser user = (TUser) ls.getLogonObject();
		String getToday = req.getParameter("getToday");

		Set<AgentClient> agents = ClientManager.getInstance().getOnlineAgents(user.getPid());
		if (agents != null) {
			int agentCount = agents.size();
			int agentOnlineCount = 0;
			int agentGoawayCount = 0;
			for (AgentClient ag : agents) {
				if (ag.getAgentConfig().getStatus().equals(AGENT_STATUS.ONLINE)) {
					agentOnlineCount++;
				} else {
					agentGoawayCount++;
				}
			}
			pandect.setAgent(agentCount, agentOnlineCount, agentGoawayCount);
		}

		Map<String, SessionWrapper> sessions = SessionManager.getInstance().getPool(user.getPid()).getSessions();
		if (sessions != null) {
			int sessionCount = sessions.size();
			int selfTalkingCount = 0;
			int agentTalkingCount = 0;
			int agentAvailableCount = 0;
			int queueingCount = 0;
			int otherCount = 0;
			for (SessionWrapper sw : sessions.values()) {
				if (sw.getSession().getStep().equals(SESSION_STEP.AGENT.name())) {
					agentTalkingCount++;
					if (sw.getVisitor() != null) {
						agentAvailableCount++;
					}
				} else if (sw.getSession().getStep().equals(SESSION_STEP.QUEUE.name())) {
					queueingCount++;
				} else if (sw.getSession().getStep().equals(SESSION_STEP.SELF.name())) {
					selfTalkingCount++;
				} else {
					otherCount++;
				}
			}
			pandect.setSession(sessionCount, selfTalkingCount, agentTalkingCount, agentAvailableCount, queueingCount, otherCount);
		}

		if (AgentConstant.YES.equals(getToday)) {
			long l = DT.getToday().getTime();
			String hql = "SELECT count(1) as sessionCount ,COUNT(DISTINCT crm) as crmCount, COUNT(DISTINCT agent) as agentCount"
					+ " FROM t_session where request_time >=" + l + " and pid='" + user.getPid() + "'";
			Session s = null;
			try {
				s = (Session) this.dao.myGetHibernateTemplateOrSessionOrConnetionOrOther();
				List o = s.createSQLQuery(hql).list();
				Object[] obj = (Object[]) o.get(0);
				pandect.setToday(CU.toi(String.valueOf(obj[0])), CU.toi(String.valueOf(obj[1])), CU.toi(String.valueOf(obj[2])));

				String hql2 = "select count(1) as agentSessionCount FROM t_session where step = '" + AgentConstant.SESSION_STEP.AGENT
						+ "' and request_time >=" + l + " and pid='" + user.getPid() + "'";
				List o2 = s.createSQLQuery(hql2).list();
				BigInteger obj2 = (BigInteger) o2.get(0);
				pandect.setTodayAgentSessionCount(obj2.intValue());
			} catch (MyException e) {
				log.error("", e.getException());
			} finally {
				if (s != null) {
					s.close();
				}
			}
		}
		Response.succObject(rep, pandect);
		log.info("[{}] get Monitor pandect cost[{}]", user.getUsername(), String.valueOf((System.currentTimeMillis() - start)));
		return null;
	}

	/**
	 * 坐席排序
	 * 
	 * @author zhengyj
	 * 
	 */
	private class AgentClientComparator implements Comparator<AgentClient> {
		private String compareType = "LOGIN_TIME";

		public AgentClientComparator(String string) {
			this.compareType = string;
		}

		@Override
		public int compare(AgentClient o1, AgentClient o2) {
			if (compareType.equals("LOGIN_TIME")) {
				return (int) (o2.getCreateTime() - o1.getCreateTime());
			} else {
				return (int) (o2.getCreateTime() - o1.getCreateTime());
			}
		}
	}

	/**
	 * 坐席监控
	 * 
	 * @param mapping
	 * @param form
	 * @param req
	 * @param rep
	 * @return
	 */
	public ActionForward agents(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse rep) {
		long start = System.currentTimeMillis();
		LogonSession ls = new LogonSession(req);
		TUser user = (TUser) ls.getLogonObject();

		List<Map> list = new ArrayList<Map>();
		Set<AgentClient> agents = ClientManager.getInstance().getOnlineAgents(user.getPid());
		if (agents != null) {
			List<AgentClient> agentList = new ArrayList<AgentClient>(agents);
			Collections.sort(agentList, new AgentClientComparator("LOGIN_TIME"));
			for (AgentClient ag : agentList) {
				Map<String, Object> oneAgent = new HashMap<String, Object>();
				oneAgent.put("agent", ag.getAgent());
				oneAgent.put("config", ag.getAgentConfig());
				oneAgent.put("loginTime", DT.getYMDHMS(ag.getCreateTime()));
				oneAgent.put("loginDuration", (System.currentTimeMillis() - ag.getCreateTime()) / 1000);
				Collection<String> sids = ag.getIdMap().values();
				int sessionsTime = 0;
				long sessionMaxTime = 0;
				if (sids != null) {
					// 正在聊天的数量
					oneAgent.put("talking", sids.size());
					SessionPool pool = SessionManager.getInstance().getPool(user.getPid());
					for (String sid : sids) {
						long time = (System.currentTimeMillis() - pool.getSession(sid).getSession().getAgentTime()) / 1000;
						if (time > sessionMaxTime) {
							sessionMaxTime = time;
						}
						sessionsTime += time;
					}
					// 聊天会话的时长
					oneAgent.put("sessionsTime", sessionsTime);
					oneAgent.put("sessionMaxTime", sessionMaxTime);
				}
				list.add(oneAgent);
			}
		}
		Response.succ(rep, list);
		log.info("[{}] get Monitor agents cost[{}]", user.getUsername(), String.valueOf((System.currentTimeMillis() - start)));
		return null;
	}

	/**
	 * 坐席排序
	 * 
	 * @author zhengyj
	 * 
	 */
	private class SessionComparator implements Comparator<SessionWrapper> {
		private String compareType = "REQUEST_TIME";

		public SessionComparator(String string) {
			this.compareType = string;
		}

		@Override
		public int compare(SessionWrapper o1, SessionWrapper o2) {
			if (compareType.equals("REQUEST_TIME")) {
				return (int) (o2.getSession().getRequestTime() - o1.getSession().getRequestTime());
			} else {
				return (int) (o2.getSession().getRequestTime() - o1.getSession().getRequestTime());
			}
		}
	}

	/**
	 * 会话监控
	 * 
	 * @param mapping
	 * @param form
	 * @param req
	 * @param rep
	 * @return
	 */
	public ActionForward sessions(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse rep) {
		String filterAgent = req.getParameter("filterAgent");
		long start = System.currentTimeMillis();
		LogonSession ls = new LogonSession(req);
		TUser user = (TUser) ls.getLogonObject();

		List<Map> list = new ArrayList<Map>();
		Map<String, SessionWrapper> sessions = SessionManager.getInstance().getPool(user.getPid()).getSessions();

		if (sessions != null) {
			List<SessionWrapper> sessionList0 = new ArrayList<SessionWrapper>(sessions.values());
			List<SessionWrapper> sessionList = null;
			if (StringUtils.isNotBlank(filterAgent) && !"null".equals(filterAgent)) {
				sessionList = new ArrayList<SessionWrapper>();
				for (int i = 0; i < sessionList0.size(); i++) {
					SessionWrapper e = sessionList0.get(i);
					if (filterAgent.equals(e.getSession().getAgent())) {
						sessionList.add(e);
					}
				}
			} else {
				sessionList = sessionList0;
			}
			Collections.sort(sessionList, new SessionComparator("REQUEST_TIME"));
			for (SessionWrapper session : sessionList) {
				Map<String, Object> oneSession = new HashMap<String, Object>();
				oneSession.put("crm", session.getCrm());
				oneSession.put("session", session.getSession());

				oneSession.put("requestTime", DT.getYMDHMS(session.getSession().getRequestTime()));
				long end = System.currentTimeMillis();
				// 处于结束的会话
				if (session.getSession().getEndTime() != null) {
					end = session.getSession().getEndTime();
				}

				int duration = (int) (end - session.getSession().getRequestTime()) / 1000;
				oneSession.put("duration", duration);
				if (session.getSession().getAgentTime() != null) {
					oneSession.put("agentTime", DT.getYMDHMS(session.getSession().getAgentTime()));
					int agentDuration = (int) (end - session.getSession().getAgentTime()) / 1000;
					oneSession.put("agentDuration", agentDuration);
				}
				if (session.getSession().getFirstAgentResponseTime() != null) {
					oneSession.put("firstAgentResponseTime", DT.getYYYYMMDDHHMMSS(new Date(session.getSession().getFirstAgentResponseTime())));
					int firstAgentResponseDuration = (int) (session.getSession().getFirstAgentResponseTime() - session.getSession().getAgentTime()) / 1000;
					oneSession.put("firstAgentResponseDuration", firstAgentResponseDuration);
				}
				list.add(oneSession);
			}
		}
		Response.succ(rep, list);
		log.info("[{}] get Monitor sessions cost[{}]", user.getUsername(), String.valueOf((System.currentTimeMillis() - start)));
		return null;
	}

	public void setUbiz(TUserBiz ubiz) {
		this.ubiz = ubiz;
	}

	public void setDao(IBaseDao dao) {
		this.dao = dao;
	}

}
